;+
; NAME:
;       OMNI_MFN_LN
;
; PURPOSE:
;       Compute a lognormal fit to a mass distribution.
;
; CATEGORY:
;       distance-omnibus Mass Suboutine
;
; CALLING SEQUENCE:
;       mu = OMNI_MFN_LN(mfn, sig, mmin, mmax, GETMMAX=getmmax, $
;                        FIXEDMIN=fixedmin, SILENT=silent)
;
; INPUTS:
;       MFN -- The masses to be used for computing the power-law fit.
;
; OPTIONAL INPUTS:
;       MAX      -- Maximum value to consider for the lognormal fit.
;       FIXEDMIN -- Fixed minimum value to use for the lognormal fit. 
;
; KEYWORD PARAMETERS:
;       GETMMAX -- Obtain M_max from the data itself.
;       SILENT  -- Dinna say a word.
;
; OUTPUTS:
;       MU -- Centroid of the lognormal fit.
;
; OPTIONAL OUTPUTS:
;       SIG  -- Gaussian width of the lognormal fit.
;       MMIN -- Minimum value over which the lognormal is valid.
;       MMAX -- Maximum value over which the lognormal is valid.
;
; COMMON BLOCKS:
;       NONE
;
; MODIFICATION HISTORY:
;
;       Created:  03/21/13, TPEB -- Initial version -- not complete!!!
;       Modified: 04/02/13, TPEB -- Completed the maximum-likelihood
;                                   section and added the iterative
;                                   version.
;       Modified: 04/03/13, TPEB -- Made memory- and disk-happy by
;                                   removing the randomly-sampled
;                                   distances for each object from the
;                                   ITER structure that is saved to
;                                   disk.  This leaves only the output
;                                   quantities for each iteration in
;                                   the structure.  Also, we now only
;                                   load up 10K distances at a time,
;                                   greatly reducing the amount of
;                                   memory required for the task.
;                                   With this change, very large
;                                   numbers of realizations are
;                                   possible.
;       Modified: 04/03/13, TPEB -- Added functionality to sample dust
;                                   temperature from a Gaussian
;                                   distribution (defined in
;                                   mass_deriv.conf) for each object,
;                                   adding an additional source of
;                                   uncertainty.
;       Modified: 04/15/13, TPEB -- Added functionality to fit a
;                                   broken power-law.
;       Modified: 05/02/13, TPEB -- Added Log-Normal fitting
;                                   functionality, and cleaned up the
;                                   way code sections are parsed and
;                                   run.  Added subroutines for PL and
;                                   LN fitting.
;       Modified: 05/09/13, TPEB -- Brought log-normal code up to
;                                   functional status, added /PL
;                                   keyword to explicitely demand
;                                   power-law fit.
;       Modified: 05/20/13, TPEB -- Added option for naming multiple
;                                   iterations of a given realization
;                                   size in the corresponding IDL save
;                                   filename.
;       Modified: 05/22/13, TPEB -- Added BROKFRAC optional input to
;                                   specify at runtime the fraction of
;                                   overlap the lower PL region has on
;                                   the upper.
;       Modified: 05/29/13, TPEB -- Ensured all output files are
;                                   properly named based on inputs.
;                                   Added SAMPLETD optional input to
;                                   override mconf.sampletd so that
;                                   messing with that config file
;                                   during testing is no longer
;                                   necessary.
;       Modified: 05/30/13, TPEB -- Fixed BROKFRAC bug (typo).
;       Modified: 06/04/13, TPEB -- Added check for PVEC structure IDL
;                                   save file, run DISTANCE_OMNIBUS if
;                                   file is not extant.
;       Modified: 06/10/13, TPEB -- Added MFNSAVE keyword, which
;                                   allows the mass function to be
;                                   saved without going through the
;                                   CPU-gymnastics of computing a
;                                   functional fit to the mfn.
;       Modified: 06/11/13, TPEB -- Changed mfn MEGA structure from
;                                   dist.xx to objs.xx for clarity.
;                                   Added /VERBOSE and /SILENT
;                                   keywords.  Fixed potential bug
;                                   with the use of REFORM. 
;       Modified: 07/17/13, TPEB -- Enforce mass floor as the 90%
;                                   completeness level as computed by
;                                   OMNI_MASS_COMPLETENESS.pro.
;       Modified: 08/21/13, TPEB -- Added support for the new GRS 13CO
;                                   kinematic distance likelihood DPDF
;                                   whereby either KDIST or GRSMATCH
;                                   must be specified for an object to
;                                   be considered for a mass.
;       Modified: 09/03/13, TPEB -- To shrink output plots for MEGA
;                                   cases, set switch to plot line
;                                   rather than open circles for data
;                                   sets larger than N=5000.
;       Modified: 02/04/14, TPEB -- Moved setup section to
;                                   OMNI_MASS_SETUP because of the
;                                   need for duplication in other mass
;                                   routines.  Consequently added the
;                                   MASS_BLOCK COMMON block for ease
;                                   of passing information back from
;                                   the new setup routine.
;       Modified: 02/28/14, TPEB -- Changed loop indices from i -->
;                                   ii, j --> jj for ease of finding.
;                                   Also, modify Monte Carlo mass
;                                   computation to also sample from
;                                   the FLUX DENSITY distribution
;                                   implied by flux +- eflux in the
;                                   catalogs.
;       Modified: 03/13/14, TPEB -- Extracted from OMNI_MASS_FUNCTION
;                                   for ease of calling from other
;                                   routines.
;
;-

;;-----------------------------------------------------------------------
;; Fit a log-normal function to the mass function  (Return = mu)
FUNCTION OMNI_MFN_LN, mfn, sig, mmin, mmax, GETMMAX=getmmax, $
                      FIXEDMIN=fixedmin, SILENT=silent
  
  COMPILE_OPT IDL2, LOGICAL_PREDICATE, HIDDEN
  
  ;; Parse Keywords
  verbose = ~KEYWORD_SET(silent)
  fixmin  = n_elements(fixedmin) GT 0
  getmmax = KEYWORD_SET(getmmax) || ~n_elements(mmax)
  IF getmmax && ~n_elements(mmax) THEN mmax = max(mfn)
  
  xmin = n_elements(mmin) ? mmin : min(mfn)
  ;; Set up user-supplied mins and maxes, as appropriate
  CASE ~getmmax + 2*fixmin OF
     0:                         ; Do nothing
     1: xmax = mmax             ; Set xmax
     2: xmin = fixedmin         ; Set xmin
     3: BEGIN                   ; Set both
        xmax = mmax
        xmin = fixedmin
     END
     ELSE: message,'Error -73: Go sip a shot of gin, and switch to coding in C.'
  ENDCASE
  
  ;; Pull indices & error check
  mind = where(mfn GE xmin, ngemin)
  IF ~ngemin THEN BEGIN
     message,'Woah, Nellie!',/cont ; Issue error message, but return
     sig = 0.                      ; zeros for mu and sig.  That'll
     RETURN,0.                     ; teach 'em to mess with me!
  ENDIF
  
  ;; Fit the log-normal function
  ;; XMIN & XMAX will be determined automatically if not specified.
  mu = lnfit( mfn[mind], sig, XMIN=xmin, XMAX=xmax, VERBOSE=verbose )
  
  ;; Set limit outputs
  mmax = xmax
  mmin = xmin
  
  RETURN, mu
END
